home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
cxref_1_4a.lha
/
parse.y
< prev
next >
Wrap
Text File
|
1997-12-07
|
36KB
|
1,433 lines
%{
/***************************************
$Header: /home/amb/cxref/RCS/parse.y 1.29 1997/11/20 19:19:07 amb Exp $
C Cross Referencing & Documentation tool. Version 1.4a.
C parser.
******************/ /******************
Written by Andrew M. Bishop
This file Copyright 1995,96,97 Andrew M. Bishop
It may be distributed under the GNU Public License, version 2, or
any higher version. See section COPYING of the GNU Public license
for conditions under which this file may be redistributed.
***************************************/
#include <string.h>
#include "parse-yy.h"
#include "cxref.h"
#include "memory.h"
/*+ A structure to hold the information about an object. +*/
typedef struct _stack
{
char *name; /*+ The name of the object. +*/
char *type; /*+ The type of the object. +*/
char *qual; /*+ The type qualifier of the object. +*/
}
stack;
#define yylex cxref_yylex
static int cxref_yylex(void);
static void yyerror(char *s);
/*+ When in a header file, some stuff can be skipped over quickly. +*/
extern int in_header;
/*+ A flag that is set to true when typedef is seen in a statement. +*/
int in_typedef=0;
/*+ The scope of the function / variable that is being examined. +*/
static int scope;
/*+ The variable must be LOCAL or EXTERNAL or GLOBAL, so this checks and sets that. +*/
#define SCOPE ( scope&(LOCAL|EXTERNAL|EXTERN_H|EXTERN_F) ? scope : scope|GLOBAL )
/*+ When in a function or a function definition, the behaviour is different. +*/
static int in_function=0,in_funcdef=0,in_funcbody=0;
/*+ The parsing stack +*/
static stack first={NULL,NULL,NULL}, /*+ first value. +*/
*list=NULL, /*+ list of all values. +*/
*current=&first; /*+ current values. +*/
/*+ The depth of the stack +*/
static int depth=0, /*+ currently in use. +*/
maxdepth=0; /*+ total malloced. +*/
/*+ Declarations that are in the same statement share this comment. +*/
static char* common_comment=NULL;
/*+ When inside a struct / union / enum definition, this is the depth. +*/
static int in_structunion=0;
/*+ When inside a struct / union definition, this is the component type. +*/
static char *comp_type=NULL;
/*+ To solve the problem where a type name is used as an identifier. +*/
static int in_type_spec=0;
/*++++++++++++++++++++++++++++++++++++++
Reset the current level on the stack.
++++++++++++++++++++++++++++++++++++++*/
static void reset(void)
{
current->name=NULL;
current->type=NULL;
current->qual=NULL;
}
/*++++++++++++++++++++++++++++++++++++++
Push a level onto the stack.
++++++++++++++++++++++++++++++++++++++*/
static void push(void)
{
if(list==NULL)
{
list=(stack*)Malloc(8*sizeof(struct _stack));
list[0]=first;
maxdepth=8;
}
else if(depth==maxdepth)
{
list=Realloc(list,(maxdepth+8)*sizeof(struct _stack));
maxdepth+=8;
}
depth++;
current=&list[depth];
reset();
}
/*++++++++++++++++++++++++++++++++++++++
Pop a level from the stack.
++++++++++++++++++++++++++++++++++++++*/
static void pop(void)
{
reset();
depth--;
current=&list[depth];
}
/*++++++++++++++++++++++++++++++++++++++
Reset the Parser, ready for the next file.
++++++++++++++++++++++++++++++++++++++*/
void ResetParser(void)
{
in_typedef=0;
scope=0;
in_function=0;
in_funcdef=0;
in_funcbody=0;
depth=0;
maxdepth=0;
if(list) Free(list);
list=NULL;
current=&first;
reset();
common_comment=NULL;
in_structunion=0;
comp_type=NULL;
in_type_spec=0;
}
%}
/* Expected conflicts: 17 shift/reduce */
%token IDENTIFIER TYPE_NAME LITERAL STRING_LITERAL ELLIPSES
%token MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
%token EQ_OP NE_OP PTR_OP AND_OP OR_OP DEC_OP INC_OP LE_OP GE_OP
%token LEFT_SHIFT RIGHT_SHIFT
%token SIZEOF
%token TYPEDEF EXTERN STATIC AUTO REGISTER CONST VOLATILE VOID INLINE
%token CHAR SHORT INT LONG SIGNED UNSIGNED FLOAT DOUBLE
%token STRUCT UNION ENUM
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
%token ASM
%start file
%%
/*-------------------- Top level --------------------*/
file
: /* Empty */
| program
;
program
: top_level_declaration
| program top_level_declaration
;
top_level_declaration
: declaration
{ scope=0; reset(); common_comment=NULL; in_typedef=0; }
| function_definition
{ scope=0; reset(); common_comment=NULL; in_typedef=0; }
| asm_statement /*+ GNU Extension +*/
| null_statement
;
/*-------------------- Declarations --------------------*/
declaration_list
: declaration
{ scope=0; reset(); common_comment=NULL; in_typedef=0; }
| declaration_list declaration
{ scope=0; reset(); common_comment=NULL; in_typedef=0;
$$=$2; }
;
declaration
: declaration_specifiers initialized_declarator_list ';'
{ in_type_spec=0; }
| declaration_specifiers ';'
{ in_type_spec=0; }
;
declaration_specifiers
: declaration_specifiers1
{ if(!in_typedef) {common_comment=GetCurrentComment(); SetCurrentComment(common_comment);} }
;
declaration_specifiers1
: storage_class_specifier
| storage_class_specifier declaration_specifiers1
{ if($1) $$=ConcatStrings(3,$1," ",$2); else $$=$2; }
| type_specifier
{ if(!current->type) current->type=$1; }
| type_specifier declaration_specifiers1
{ if(!current->type) current->type=$1;
$$=ConcatStrings(3,$1," ",$2); }
| type_qualifier
| type_qualifier declaration_specifiers1
{ $$=ConcatStrings(3,$1," ",$2); }
;
/* Initialised declarator list */
initialized_declarator_list
: initialized_declarator
| initialized_declarator_list ',' { in_type_spec=1; } initialized_declarator
;
initialized_declarator
: initialized_declarator1
{
if(!in_function && !in_funcdef && !in_structunion)
{
char* specific_comment=GetCurrentComment();
if(!common_comment) SetCurrentComment(specific_comment); else
if(!specific_comment) SetCurrentComment(common_comment); else
if(common_comment!=specific_comment) SetCurrentComment(ConcatStrings(3,common_comment," ",specific_comment)); else
SetCurrentComment(common_comment);
}
if(in_typedef)
{
char* vname=strstr($1,current->name);
SeenTypedefName(current->name,vname[strlen(current->name)]=='('?-1:1);
if(!in_header)
SeenTypedef(current->name,ConcatStrings(3,current->qual,current->type,$1));
}
else
if(in_function==2)
SeenFunctionArg(current->name,ConcatStrings(3,current->qual,current->type,$1));
else
{
char* vname=strstr($1,current->name);
if(vname[strlen(current->name)]!='(' && IsATypeName(current->type)!='f')
{
if((in_funcbody==0 || scope&EXTERN_F) && !in_structunion && !(in_header==GLOBAL && scope&EXTERN_H))
SeenVariableDefinition(current->name,ConcatStrings(3,current->qual,current->type,$1),SCOPE);
else
if(in_funcbody)
SeenScopeVariable(current->name);
}
else
{
SeenFunctionProto(current->name,in_funcbody);
DownScope();
}
}
if(in_function==3) in_function=0;
}
;
initialized_declarator1
: declarator
| declarator asm_label /*+ GNU Extension +*/
| declarator initializer_part
| declarator asm_label initializer_part /* GNU Ext